/**
 * Copyright 2000 self.com.au
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. (http://www.apache.org/licenses/LICENSE-2.0)
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
 * the specific language governing permissions and limitations under the License.
 *
 * <dhamma-message src="Atisha (11th century Tibetan Buddhist master)">
 * 	The greatest achievement is selflessness. The greatest worth is self-mastery.
 * 	The greatest quality is seeking to serve others. The greatest precept is continual awareness.
 * 	The greatest medicine is the emptiness of everything. The greatest action is not conforming with the worlds ways.
 * 	The greatest magic is transmuting the passions. The greatest generosity is non-attachment.
 * 	The greatest goodness is a peaceful mind. The greatest patience is humility.
 * 	The greatest effort is not concerned with results. The greatest meditation is a mind that lets go.
 * 	The greatest wisdom is seeing through appearances. 
 * </dhamma-message>
 *
 * @author Ashin Wimalajeewa
 */
package self.amigo.elem;

import java.awt.*;
import java.awt.geom.*;
import java.util.*;

final public class PolygonEffectUtils {
  /**
   *
   *    5  6  7
   *      \|/
   *    4 -+- 0
   *      /|\
   *    3  2  1
   *
   */

  static public int[] initOriginPoint( Rectangle fig, int dir ) {
    int[] ret = {fig.x, fig.y};
    int midHeight = fig.height / 2;
    int midWidth = fig.width / 2;
    if ( dir == 5 || dir == 4 || dir == 3 )   // x-axis
      ret[0] = fig.x + fig.width;
    if ( dir == 5 || dir == 6 || dir == 7 )   // y-axis
      ret[1] = fig.y + fig.height;
    if ( dir == 2 || dir == 6 )               // x-axis
      ret[0] = fig.x + midWidth;
    if ( dir == 4 || dir == 0 )               // y-axis
      ret[1] = fig.y + midHeight;
    return ret;
  }

  static public int[] initDestinationPoint( int[] origin, Rectangle fig, int dir, int len ) {
    boolean fromPerimeter = (dir < 8);
    boolean lenZero = (len == 0);
    if ( !fromPerimeter )
      dir = dir - 8;
    int[] ret = new int[2];

    ret[0] = origin[0]; ret[1] = origin[1];
//    if ( fromPerimeter )
//      len = fig.width;
    if ( dir == 7 || dir == 0 || dir == 1 )   // x-axis
      ret[0] = (lenZero ? fig.x + fig.width: origin[0] + len);
    if ( dir == 5 || dir == 4 || dir == 3 )   // x-axis
      ret[0] = (lenZero ? fig.x: origin[0] - len);
//    if ( fromPerimeter )
//      len = fig.height;
    if ( dir == 5 || dir == 6 || dir == 7 )   // y-axis
      ret[1] = (lenZero ? fig.y: origin[1] - len);
    if ( dir == 3 || dir == 2 || dir == 1 )   // y-axis
      ret[1] = (lenZero ? fig.y + fig.height: origin[1] + len);
    return ret;
  }

  // order: north, south, east, west
  static private Area[] getCentreEffectAreas( Polygon polygon, Rectangle fig ) {
    int top = fig.y, left = fig.x, bottom = top + fig.height, right = left + fig.width;
    int centerx = left + (fig.width/2), centery = top + (fig.height/2);
    Polygon north = new Polygon( new int[] {left, right, centerx}, new int[] {top, top, centery}, 3 );
    Polygon south = new Polygon( new int[] {left, right, centerx}, new int[] {bottom, bottom, centery}, 3 );
    Polygon east = new Polygon( new int[] {right, right, centerx}, new int[] {top, bottom, centery}, 3 );
    Polygon west = new Polygon( new int[] {left, left, centerx}, new int[] {top, bottom, centery}, 3 );

    Area polygonArea = new Area( polygon );
    Area northArea = new Area( north );
    Area southArea = new Area( south );
    Area eastArea = new Area( east );
    Area westArea = new Area( west  );

    northArea.intersect( polygonArea );
    southArea.intersect( polygonArea );
    eastArea.intersect( polygonArea );
    westArea.intersect( polygonArea );

    Area[] ret = new Area[] {northArea, southArea, eastArea, westArea };
    return ret;
  }

  static public ArrayList assembleEffect( Polygon source, Color c1, Color c2, int dir, int len, boolean cyclic ) {
    ArrayList ret = new ArrayList();
    Rectangle fig = source.getBounds();
    int[] origin;
    if ( dir > 7 && dir <= 16 )
      origin = new int[] {fig.x + (fig.width)/2, fig.y + (fig.height/2) };
    else
      origin = PolygonEffectUtils.initOriginPoint( fig, dir );
    if ( dir == 16 ) {
      Area[] directionAreas = getCentreEffectAreas( source, fig );
      int[] dirs = new int[] { 6, 2, 0, 4 };
      for ( int cntr = 0; cntr < dirs.length; cntr++ ) {
        int[] dest = PolygonEffectUtils.initDestinationPoint( origin, fig, dirs[cntr] + 8, len );
        GradientPaint gp = new GradientPaint( origin[0], origin[1], c1, dest[0], dest[1], c2, cyclic );
        GradientPaintShape effect = new GradientPaintShape( gp, directionAreas[cntr] );
        ret.add( effect );
      }
    } else {
      int[] dest = PolygonEffectUtils.initDestinationPoint( origin, fig, dir, len );
      GradientPaint gp = new GradientPaint( origin[0], origin[1], c1, dest[0], dest[1], c2, cyclic );
      GradientPaintShape effect = new GradientPaintShape( gp, source );
      ret.add( effect );
    }
    return ret;
  }

  static public class GradientPaintShape {
    public GradientPaint gradientPaint;
    public Shape         shape;

    public GradientPaintShape( GradientPaint gp, Shape s ) {
      gradientPaint = gp;
      shape = s;
    }
  }

  static public void main( String[] args ) {
    // 1:100
    int dir = 15;
    int len = 0;
    Rectangle rect = new Rectangle( 0, 0, 200, 100 );
//    int orig[] = initOriginPoint( rect, dir );
    int orig[] = new int[] {rect.x + (rect.width)/2, rect.y + (rect.height/2) };
    int dest[] = initDestinationPoint( orig, rect, dir, len );
    System.out.println("rect=" + rect );
    System.out.println("o->" + orig[0] + ", " + orig[1] );
    System.out.println("d->" + dest[0] + ", " + dest[1] );
  }
}
